package com.frogs.ucenter.component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.ArrayUtils;
import org.jsoup.Connection.Method;
import org.jsoup.Jsoup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.frogs.framework.util.PriceUtil;
import com.frogs.framework.util.StringUtil;
import com.frogs.framework.util.UrlUtil;
import com.frogs.system.util.ApiUrlParamEnum;
import com.frogs.system.util.ApplicablePlatformEnum;
import com.frogs.system.util.CouponTypeEnum;
import com.frogs.system.util.OpenPlatformEnum;
import com.frogs.system.util.PromotionApplicablePlatformEnum;
import com.frogs.system.util.TraceConstants;
import com.frogs.system.web.api.entity.ApiUrl;
import com.frogs.system.web.api.response.Response.ApiResultEnum;
import com.frogs.system.web.api.response.Response.ResultParamEnum;
import com.frogs.ucenter.util.CommonRequestApiUtil;

@Component("requestApiHelper")
public class RequestApiHelper extends CommonRequestApiUtil{
	
	private Logger log = LoggerFactory.getLogger(RequestApiHelper.class);
	private Map<Integer, Integer> platformMap = new HashMap<Integer, Integer>(); 
	
	public RequestApiHelper() {
		//渠道标示码键值对
		platformMap.put(-1, TraceConstants.TRACE_UC_CHANNEL_GW);
		platformMap.put(OpenPlatformEnum.WECHAT_MALL.getId(), TraceConstants.TRACE_UC_CHANNEL_WECHAT_SC);
		platformMap.put(OpenPlatformEnum.WECHAT_HDC.getId(), TraceConstants.TRACE_UC_CHANNEL_WECHAT_XYJ);
		platformMap.put(OpenPlatformEnum.WECHART_QR.getId(), TraceConstants.TRACE_UC_CHANNEL_WECHAT_SM);
		platformMap.put(OpenPlatformEnum.QQ.getId(), TraceConstants.TRACE_UC_CHANNEL_QQ);
		platformMap.put(OpenPlatformEnum.SINAWEIBO.getId(), TraceConstants.TRACE_UC_CHANNEL_SINA_WB);
		platformMap.put(OpenPlatformEnum.ALIPAY.getId(), TraceConstants.TRACE_UC_CHANNEL_ZFB);
		platformMap.put(OpenPlatformEnum.LANHAI.getId(), TraceConstants.TRACE_UC_CHANNEL_LH);
	}
	
	/**
	 * 获取商城资讯
	 * @return
	 */
	public JSONArray listEvents() {
		ApiUrl apiUrl = this.buildMallApiBaseUrl("MALL_EVENT_LIST");
		try{
			JSONObject json = (JSONObject) this.requestApi(apiUrl.getUrl(), Method.POST, apiUrl.getKeyvals());
			if(null != json 
					&& ApiResultEnum.SUCCESS.getId() == json.getJSONObject("response").getIntValue("code")
					&& json.getJSONObject("response").containsKey("list")) {
					return json.getJSONObject("response").getJSONArray("list");
				}
		} catch (Exception e) {
			log.error("func[listEvents] error[" + e.getMessage() + "]");
		}
		return null;
	}
	
	/**
	 * 根据商品id获取同宗商品ids
	 * 
	 * @param goodsId
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public List<Integer> getGoodsSimilarList(Integer goodsId) {
		List<Integer> list = new ArrayList<Integer>();
		ApiUrl apiUrl = this.buildMallApiBaseUrl("MALL_GOODS_SIMILAR_LIST");
		String[] otherParams = {ApiUrlParamEnum.goodsId.getParamName(), goodsId.toString()};
		String[] allParams = (String[]) ArrayUtils.addAll(apiUrl.getKeyvals(), otherParams);
		JSONObject result = null;
		list.add(goodsId);
		try{
			result = (JSONObject) this.requestApi(apiUrl.getUrl(), Method.POST, allParams);
			if (ApiResultEnum.SUCCESS.getId() != result.getJSONObject("response").getIntValue(ResultParamEnum.code.getParamName()))
				throw new IllegalStateException(result.getJSONObject("response").getString(ResultParamEnum.tip.getParamName()));
			JSONArray jsr = result.getJSONObject("response").getJSONArray("list");
			List<Map> similarList = JSONObject.parseArray(jsr.toJSONString(), Map.class);
			if (similarList != null) {
				for(int i=0; i<similarList.size(); i++) {
					Integer relateGoodsId = (Integer) similarList.get(i).get("relateGoodsId");
					list.add(relateGoodsId);
				}
			}
			return list;
		} catch (Exception e) {
			log.error("func[getUser] url[{}] exception[{} - {}] desc[fail]",
					new Object[] { apiUrl.getUrl(), e.getMessage(), Arrays.deepToString(e.getStackTrace()) });
		}
		return list;
	}
	
	/**
	 * 获取订单状态
	 * @param orderSn
	 * @return
	 */
	public JSONObject getOrderStatus(String orderSn) {
		ApiUrl apiUrl = this.buildMallApiBaseUrl("MALL_ORDER_STATUS");
		String[] otherParams = {ApiUrlParamEnum.orderSn.getParamName(),orderSn};
		String[] allParams = (String[])ArrayUtils.addAll(apiUrl.getKeyvals(), otherParams);
		try{
			return (JSONObject) this.requestApi(apiUrl.getUrl(), Method.POST, allParams);
		} catch (Exception e) {
			log.error("func[getOrderStatus] url[{}] params[{}] exception[{} - {}] desc[fail]",
					new Object[] { apiUrl.getUrl(), Arrays.deepToString(apiUrl.getKeyvals()) , e.getMessage(), Arrays.deepToString(e.getStackTrace()) });
		}
		return null;
	}
	
	/**
	 * 添加购物车快照
	 * @param addRequest
	 */
	public void addShoppingCartSnap(JSONObject object) {
		if (object.getInteger("applicablePlatformId") == ApplicablePlatformEnum.HTML5.getId()) {
			return;
		}
		JSONObject goodsJson = new JSONObject();
		goodsJson.put("mealId", object.getInteger("mealId"));
		goodsJson.put("selected", object.getInteger("isChecked"));
		goodsJson.put("quantity", object.getInteger("number"));
		goodsJson.put("catIds", object.getString("catIds"));
		goodsJson.put("tags", object.getString("tags"));
		goodsJson.put("brandId", object.getInteger("brandId"));
		goodsJson.put("price", object.getDouble("price"));
		goodsJson.put("skuId", object.getInteger("skuId"));
		goodsJson.put("subTotal", PriceUtil.multiple(object.getDouble("price"), object.getInteger("number")));
		goodsJson.put("isSeckill", object.getInteger("isSeckill"));
		goodsJson.put("createTime", new Date());
		
		ApiUrl apiUrl = this.buildPromotionApiBaseUrl("PROMOTION_SHOPPINGCART_SNAP_ADD");
		String[] otherParams = {ApiUrlParamEnum.goods.getParamName(),goodsJson.toJSONString(),
				ApiUrlParamEnum.userId.getParamName(), String.valueOf(object.getInteger("userId")),
				ApiUrlParamEnum.userTraceId.getParamName(), StringUtil.isEmpty(object.getString("userTraceId")) ? "" : object.getString("userTraceId"),
				ApiUrlParamEnum.applicablePlatformId.getParamName(), PromotionApplicablePlatformEnum.NEW_MALL.getId() + ""};
		String[] allParams = (String[])ArrayUtils.addAll(apiUrl.getKeyvals(), otherParams);
		
		try{
			log.info("func[addShoppingCartSnap] url==" + apiUrl.getUrl() + ",params" + ArrayUtils.toString(allParams));
			this.requestApi(apiUrl.getUrl(), Method.POST, allParams);
		} catch (Exception e) {
			log.error("func[addShoppingCartSnap] url[{}] params[{}] exception[{} - {}] desc[fail]",
					new Object[] { apiUrl.getUrl(), Arrays.deepToString(apiUrl.getKeyvals()) , e.getMessage(), Arrays.deepToString(e.getStackTrace()) });
		}
	}
	
	/**
	 * 删除购物车快照商品
	 * @param addRequest
	 */
	public void removeShoppingCartSnap(Integer mealId, Integer skuId, JSONObject object) {
		
		ApiUrl apiUrl = this.buildPromotionApiBaseUrl("PROMOTION_SHOPPINGCART_SNAP_REMOVE");
		String[] otherParams = { 
				ApiUrlParamEnum.mealId.getParamName(), StringUtil.isEmpty(mealId)?"":mealId + "",
				ApiUrlParamEnum.userId.getParamName(),  StringUtil.isEmpty(object.getInteger("userId"))?"":object.getInteger("userId") + "",
				ApiUrlParamEnum.userTraceId.getParamName(), StringUtil.isEmpty(object.getString("userTraceId"))?"":object.getString("userTraceId"),
				ApiUrlParamEnum.skuId.getParamName(),skuId+"",
				ApiUrlParamEnum.applicablePlatformId.getParamName(), PromotionApplicablePlatformEnum.NEW_MALL.getId() + ""};
		String[] allParams = (String[])ArrayUtils.addAll(apiUrl.getKeyvals(), otherParams);
		log.info("func[removeShoppingCartSnap] url=" + apiUrl.getUrl() + ",params=" + JSONObject.toJSONString(allParams));
		
		try{
			this.requestApi(apiUrl.getUrl(), Method.POST, allParams);
		} catch (Exception e) {
			log.error("func[removeShoppingCartSnap] url[{}] params[{}] exception[{} - {}] desc[fail]",
					new Object[] { apiUrl.getUrl(), Arrays.deepToString(apiUrl.getKeyvals()) , e.getMessage(), Arrays.deepToString(e.getStackTrace()) });
		}
	}
	
	public void mergeShoppingCartSnap(JSONObject object, int isUserCartNull, int isVisitorCartNull ) {
		
		ApiUrl apiUrl = this.buildPromotionApiBaseUrl("PROMOTION_SHOPPINGCART_SNAP_MERGE");
		String[] otherParams = {
				ApiUrlParamEnum.userId.getParamName(), object.getInteger("userId") + "",
				ApiUrlParamEnum.userTraceId.getParamName(), StringUtil.isEmpty(object.getString("userTraceId"))?"":object.getString("userTraceId"),
				ApiUrlParamEnum.applicablePlatformId.getParamName(), PromotionApplicablePlatformEnum.NEW_MALL.getId() + "",
				ApiUrlParamEnum.shoppingCart.getParamName(), isUserCartNull + "," + isVisitorCartNull};
		String[] allParams = (String[])ArrayUtils.addAll(apiUrl.getKeyvals(), otherParams);
		
		try{
			this.requestApi(apiUrl.getUrl(), Method.POST, allParams);
			log.info("func[mergeShoppingCartSnap] url=" + apiUrl.getUrl() + ",params=" + JSONObject.toJSONString(allParams));
		} catch (Exception e) {
			log.error("func[mergeShoppingCartSnap] url[{}] params[{}] exception[{} - {}] desc[fail]",
					new Object[] { apiUrl.getUrl(), Arrays.deepToString(apiUrl.getKeyvals()) , e.getMessage(), Arrays.deepToString(e.getStackTrace()) });
		}
	}
	
	public JSONObject giveCard(Integer userId, Integer giveCardId) {
		ApiUrl apiUrl = this.buildPromotionApiBaseUrl("COUPON_USER_GEN");
		String[] otherParams = {ApiUrlParamEnum.userId.getParamName(), userId.toString(),
				ApiUrlParamEnum.couponId.getParamName(), String.valueOf(giveCardId),
				ApiUrlParamEnum.bindStatus.getParamName(), String.valueOf(CouponTypeEnum.BIND_BOUND.getId()),
				ApiUrlParamEnum.applicablePlatformId.getParamName(), PromotionApplicablePlatformEnum.NEW_MALL.getId()+""
				};
		String[] allParams = (String[])ArrayUtils.addAll(apiUrl.getKeyvals(), otherParams);
		log.info("func[giveCard] url["+apiUrl.getUrl()+"] userId["+userId+"] giveCardId["+giveCardId+"] desc[get card before]");
		try{
			return (JSONObject)this.requestApi(apiUrl.getUrl(), Method.POST, allParams);
		} catch (Exception e) {
			log.error("func[giveCard] url[{}] params[{}] exception[{} - {}] desc[fail]",
					new Object[] { apiUrl.getUrl(), Arrays.deepToString(apiUrl.getKeyvals()) , e.getMessage(), Arrays.deepToString(e.getStackTrace()) });
		}
		log.info("func[giveCard] userId["+userId+"] giveCardId["+giveCardId+"] desc[get card end]");
		return null;
	}
	
	public JSONObject giveRedPack(String openId, Integer giveRedPackId) {
		ApiUrl apiUrl = this.buildWxpayApiBaseUrl("RED_PACK_APPLY");
		String[] otherParams = {ApiUrlParamEnum.openId.getParamName(), openId,
				ApiUrlParamEnum.redPackId.getParamName(), String.valueOf(giveRedPackId),
				};
		String[] allParams = (String[])ArrayUtils.addAll(apiUrl.getKeyvals(), otherParams);
		log.info("func[giveRedPack] url["+apiUrl.getUrl()+"] openId["+openId+"] giveRedPackId["+giveRedPackId+"] desc[get card before]");
		try{
			return (JSONObject)this.requestApi(apiUrl.getUrl(), Method.GET, allParams);
		} catch (Exception e) {
			log.error("func[giveRedPack] url[{}] params[{}] exception[{} - {}] desc[fail]",
					new Object[] { apiUrl.getUrl(), Arrays.deepToString(apiUrl.getKeyvals()) , e.getMessage(), Arrays.deepToString(e.getStackTrace()) });
		}
		log.info("func[giveRedPack] openId["+openId+"] giveRedPackId["+giveRedPackId+"] desc[get card end]");
		return null;
	}
	
	public JSONObject verifyPermission(String url, String appId, String ip, Integer userId, String verify) {
		JSONObject object = new JSONObject();
		String sendUrl="http://open.frogshealth.com/permission/verify.jsonp";
		String[] keyvals = {
				ApiUrlParamEnum.openUrl.getParamName(),UrlUtil.encode(url, "utf-8"),
				ApiUrlParamEnum.appId.getParamName(),appId,
				ApiUrlParamEnum.ip.getParamName(), ip,
				ApiUrlParamEnum.userId.getParamName(), userId.toString(),
				ApiUrlParamEnum.verify.getParamName(), verify,
			};
		try {
			String result = Jsoup.connect(sendUrl).method(Method.POST).data(keyvals).ignoreContentType(true).timeout(5000).execute().body();
			object = JSONObject.parseObject(result);
		} catch (IOException e) {
			log.error("func[{}] parameterMap[{}] exception[{} - {}] desc[fail]",//
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(), Arrays.deepToString(keyvals), e.getMessage(), Arrays.deepToString(e.getStackTrace()) });
		}
		return object;
	}
	
	@Async
	public JSONObject initAlertReceive(int userId, int followedUserId, int type, int openPlatformId) {
		ApiUrl apiUrl = this.buildDatacenterApiBaseUrl("RECEIVE_ALERT_INIT");
		String[] otherParams = {
				ApiUrlParamEnum.userId.getParamName(), userId + "",
				ApiUrlParamEnum.dataTypeId.getParamName(), -1+"",
				ApiUrlParamEnum.followedUserId.getParamName(), followedUserId + "",
				ApiUrlParamEnum.type.getParamName(), type + "",
				ApiUrlParamEnum.openPlatformId.getParamName(), openPlatformId + ""
				};
		String[] allParams = (String[])ArrayUtils.addAll(apiUrl.getKeyvals(), otherParams);
		try{
			return (JSONObject)this.requestApi(apiUrl.getUrl(), Method.GET, allParams);
		} catch (Exception e) {
			log.error("func[giveRedPack] url[{}] params[{}] exception[{} - {}] desc[fail]",
					new Object[] { apiUrl.getUrl(), Arrays.deepToString(apiUrl.getKeyvals()) , e.getMessage(), Arrays.deepToString(e.getStackTrace()) });
		}
		return null;
	}
	
	public String getAccessToken(Integer openPlatformId) {
		String accessToken = "";
		String sendUrl="http://open.frogshealth.com/wechatAppInfo/detail.jsonp";
		String[] keyvals = {
				ApiUrlParamEnum.openPlatformId.getParamName(), openPlatformId.toString()
			};
		try {
			String result = Jsoup.connect(sendUrl).method(Method.POST).data(keyvals).ignoreContentType(true).timeout(5000).execute().body();
			JSONObject object = JSONObject.parseObject(result);
			log.info("getAccessToken="+object.toJSONString());
			if (object.getJSONObject("response").getInteger("code") == ApiResultEnum.SUCCESS.getId()) {
				JSONObject wechatAppInfo = object.getJSONObject("response").getJSONObject("info");
				accessToken = wechatAppInfo.getString("accessToken");
			}
		} catch (IOException e) {
			log.error("func[{}] parameterMap[{}] exception[{} - {}] desc[fail]",//
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(), Arrays.deepToString(keyvals), e.getMessage(), Arrays.deepToString(e.getStackTrace()) });
		}
		return accessToken;
	}
	
}
